home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / xlib / xcbitmap / xcbitmap.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1995-04-15  |  6.7 KB  |  287 lines

  1. #include "quicky.hpp"
  2. #include "xbmtools.h"
  3. #include "xcbitmap.h"
  4. #include "xlib_all.h"
  5.  
  6. /* these are here instead of the header file because they're not part
  7.    of the library interface */
  8.  
  9. // rol al,1
  10. #define ROL_AL          0xc0d0
  11. // mov [esi + disp8], imm8
  12. #define SHORT_STORE_8   0x46c6
  13. // mov [esi + disp32], imm8
  14. #define STORE_8         0x86c6
  15. // mov [esi + disp8], imm16
  16. #define SHORT_STORE_32  0x46c7
  17. // mov [esi + disp32], imm16
  18. #define STORE_32        0x86c7
  19. // adc esi, imm8
  20. #define ADC_SI_IMMED    0xd683
  21. // out dx, al
  22. #define OUT_AL          0xee
  23. // ret
  24. #define RETURN          0xc3
  25. // 16-bit prefix
  26. #define WORD_PREFIX    0x66
  27.  
  28.  
  29.  
  30. int output_used = 0;
  31.  
  32.  
  33.  
  34. uchar ColumnMask[]= { 0x11,0x22,0x44,0x88 };
  35.  
  36. /*
  37. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  38. ; _x_put_cbitmap
  39. ;
  40. ; Displays a compiled bitmap generated by x_compile_bitmap at given
  41. ; coordinates, on a given screen page.
  42. ;
  43. ; C near-callable as:
  44. ; void x_put_cbitmap (int XPos, int YPos,
  45. ;                     unsigned int PageOffset, char far * Sprite);
  46. ; ax, bx, cx, and dx are squashed like insignificant insects.
  47. */
  48.  
  49. extern void asm_x_put_cbitmap(ushort XPos, ushort YPos, ushort PageOffset, char * Sprite);
  50.  
  51. #pragma aux asm_x_put_cbitmap=    \
  52.     "push esi"        \
  53.                 \
  54.     "mov edx, [ScrnLogicalByteWidth]"    \
  55.     "mul edx"        \
  56.     "and ebx, 0x0ffff"    \
  57.     "mov esi, ebx"        \
  58.     "sar esi, 2"        \
  59.     "and eax, 0x0ffff"    \
  60.     "add esi, eax"        \
  61.     "and ecx, 0x0ffff"    \
  62.     "add esi, ecx"        \
  63.     "add esi, 128"        \
  64.     "add esi, 0xa0000"    \
  65.                 \
  66.     "and ebx, 3"        \
  67.     "mov ah, ColumnMask[ebx]"    \
  68.                 \
  69.     "mov dx, 0x3c4"        \
  70.     "mov al, 0x02"        \
  71.     "out dx, ax"        \
  72.     "inc dx"        \
  73.     "mov al, ah"        \
  74.                 \
  75.     "call edi"        \
  76.                 \
  77.     "pop esi"        \
  78.     parm [bx] [ax] [cx] [edi]    \
  79.     modify [edx];
  80.  
  81.  
  82. // if asm_x_put_cbitmap was called directly from outside code, the compiler
  83. // couldn't find the function
  84. void x_put_cbitmap(ushort XPos, ushort YPos, ushort PageOffset, char * Sprite)
  85. {
  86.     asm_x_put_cbitmap(XPos,YPos,PageOffset,Sprite);
  87. }
  88.  
  89.  
  90. // converted these to functions because otherwise the compiler optimized code
  91. // too well, having some bad/buggy side-effects in x_compile_bitmap
  92. void Emitb(char * output, uchar x)
  93. {
  94.     *(output + output_used) = x;
  95.     output_used++;
  96. }
  97.  
  98. void Emitw(char * output, ushort x)
  99. {
  100.     *(output + output_used) = x & 255;
  101.     *(output + output_used+1) = x >> 8;
  102.     output_used += 2;
  103. }
  104.  
  105. // emit double word
  106. void Emitd(char * output, ulong x)
  107. {
  108.     *(output + output_used) = x & 255;
  109.     *(output + output_used+1) = x >> 8;  
  110.     *(output + output_used+2) = x >> 16; 
  111.     *(output + output_used+3) = x >> 24;
  112.     output_used += 4;
  113. }
  114.  
  115. int x_compile_bitmap (int logical_screen_width, char * bitmap, char * output)
  116. {
  117.     long pos;
  118.     int pix0, pix1, pix2, pix3, numpix;
  119.     int column = 0, set_column = 0;
  120.     int scanx = 0, scany = 0;
  121.  
  122.     int height = LBMHeight(bitmap);
  123.     int width = LBMWidth(bitmap);
  124.     int margin = width - 1;
  125.     int margin2 = margin - 4;
  126.     int margin4 = margin - 12;
  127.  
  128.     output_used = 0;        // must reset this on every compile
  129.  
  130.     while (column < 4) {
  131.         numpix = 1;
  132.         pix0 = LBMGetPix(scanx, scany, bitmap);
  133.         if (pix0 != 0) {
  134.             if (set_column != column) {
  135.                 do {
  136.                     Emitw (output, ROL_AL);
  137.                     Emitw (output, ADC_SI_IMMED);
  138.                     Emitb (output, 0);
  139.                     set_column++;
  140.                 } while (set_column != column);
  141.                 Emitb (output, OUT_AL);
  142.             }
  143.             if (scanx <= margin2) {
  144.                 pix1 = LBMGetPix(scanx + 4, scany, bitmap);
  145.                 if ((pix1 != 0)
  146.                   &&(scanx <= margin4)) {
  147.                     numpix = 2;
  148.                     pix2 = LBMGetPix(scanx + 8, scany, bitmap);
  149.                     pix3 = LBMGetPix(scanx + 12, scany, bitmap);
  150.                     if ((pix2 != 0) && (pix3 != 0)) {
  151.                         numpix = 4;
  152.                     }
  153.                 }
  154.             }
  155.             pos = (scany * logical_screen_width) + (scanx >> 2) - 128;
  156.             if ((pos >= -128) && (pos <= 127)) {
  157.                 if (numpix == 1) {
  158.                     Emitw (output, SHORT_STORE_8);
  159.                     Emitb (output, pos);
  160.                     Emitb (output, pix0);
  161.                 } else {
  162.                     if( numpix != 4 )
  163.                         Emitb (output, WORD_PREFIX);
  164.                     Emitw (output, SHORT_STORE_32);
  165.                     Emitb (output, pos);
  166.                     Emitb (output, pix0);
  167.                     Emitb (output, pix1);
  168.                     if (numpix == 4) {
  169.                         Emitb (output, pix2);
  170.                         Emitb (output, pix3);
  171.                     }
  172.                 }
  173.             } else {
  174.                 if (numpix == 1) {
  175.                     Emitw (output, STORE_8);
  176.                     Emitd (output, pos);
  177.                     Emitb (output, pix0);
  178.                 } else {
  179.                     if( numpix != 4 )
  180.                         Emitb (output, WORD_PREFIX);
  181.                     Emitw (output, STORE_32);
  182.                     Emitd (output, pos);
  183.                     Emitb (output, pix0);
  184.                     Emitb (output, pix1);
  185.                     if (numpix == 4) {
  186.                         Emitb (output, pix2);
  187.                         Emitb (output, pix3);
  188.                     }
  189.                 }
  190.             }
  191.         }
  192.         scanx += (numpix << 2);
  193.         if (scanx > margin) {
  194.             scanx = column;
  195.             scany++;
  196.             if (scany == height) {
  197.                 scany = 0;
  198.                 column++;
  199.                 scanx=column;    // this was missing in original
  200.                         // and caused a bug: the first
  201.                         // line of bitmap was shifted
  202.                         // right one pixel
  203.             }
  204.         }
  205.     }
  206.     Emitb(output, RETURN);
  207.     return(output_used);
  208. }
  209.  
  210.  
  211. int x_sizeof_cbitmap (int logical_screen_width, char * bitmap)
  212. {
  213.     int pix0, pix1, pix2, pix3, numpix, pos;
  214.     int column = 0, set_column = 0;
  215.     int scanx = 0, scany = 0;
  216.     int output_used = 1;
  217.  
  218.     int height = LBMHeight(bitmap);
  219.     int width = LBMWidth(bitmap);
  220.     int margin = width - 1;
  221.     int margin2 = margin - 4;
  222.     int margin4 = margin - 12;
  223.  
  224.     while (column < 4) {
  225.         numpix = 1;
  226.         pix0 = LBMGetPix(scanx, scany, bitmap);
  227.         if (pix0 != 0) {
  228.             if (set_column != column) {
  229.                 do {
  230.                     output_used += 5;
  231.                     set_column++;
  232.                 } while (set_column != column);
  233.                 output_used++;
  234.             }
  235.             if (scanx <= margin2) {
  236.                 pix1 = LBMGetPix(scanx + 4, scany, bitmap);
  237.                 if ((pix1 != 0)
  238.                   &&(scanx <= margin4)) {
  239.                     numpix = 2;
  240.                     pix2 = LBMGetPix(scanx + 8, scany, bitmap);
  241.                     pix3 = LBMGetPix(scanx + 12, scany, bitmap);
  242.                     if ((pix2 != 0) && (pix3 != 0)) {
  243.                         numpix = 4;
  244.                     }
  245.                 }
  246.             }
  247.             pos = (scany * logical_screen_width) + (scanx >> 2) - 128;
  248.             if ((pos >= -128) && (pos <= 127)) {
  249.                 if (numpix == 1) {
  250.                     output_used += 4;
  251.                 } else {
  252.                     if( numpix != 4 )
  253.                         output_used++;
  254.                     output_used += 5;
  255.                     if (numpix == 4)
  256.                         output_used += 2;
  257.                 }
  258.             } else {
  259.                 if (numpix == 1) {
  260.                     output_used += 7;
  261.                 } else {
  262.                     if( numpix !=4 )
  263.                         output_used++;
  264.                     output_used += 8;
  265.                     if (numpix == 4)
  266.                         output_used += 2;
  267.                 }
  268.             }
  269.         }
  270.         scanx += (numpix << 2);
  271.         if (scanx > margin) {
  272.             scanx = column;
  273.             scany++;
  274.             if (scany == height) {
  275.                 scany = 0;
  276.                 column++;
  277.                 scanx=column;    // this was missing in original
  278.                         // and caused a bug: the first
  279.                         // line of bitmap was shifted
  280.                         // right one pixel
  281.             }
  282.         }
  283.     }
  284.     return(output_used);
  285. }
  286.  
  287.